#include <AL/alut.h>
#include <iostream>

#ifdef SYPX_MEMCHECK
#include "mmgr.h"
#endif

#include "ResourceManager.h"
#include "Types.h"
#include "AudioEngineOAL.h"
#include "SoundBuffer.h"
#include "Engine.h"
#include "Canvas.h"


namespace SypX
{
	AudioEngineOAL::AudioEngineOAL(void)
	{
		std::cout<<Engine::getSingleton()->getCanvas()->getElapsedTime()<<" Begin alc Init\n";
		alutInit (0, 0);


		/*
		// Initialization handled by alut
		device = alcOpenDevice(NULL); // select the "preferred device"
		if (device) {
			// use the device to make a context
			context=alcCreateContext(device,NULL);
			// set my context to the currently active one
			alcMakeContextCurrent(context);
		}
		 */

		std::cout<<Engine::getSingleton()->getCanvas()->getElapsedTime()<<" Alut Init End\n";
		// Generate sources to playback the Buffer
		alGenSources( NUMSOURCES, source );
		setListenerPos(Vec3(0,0,0));
	}

	void AudioEngineOAL::playMusic(const String& file, bool loop )
	{

	}

	void AudioEngineOAL::stopMusic()
	{

	}

	AudioEngineOAL::~AudioEngineOAL(void)
	{
		alDeleteSources(NUMSOURCES, source);

		alutExit();
		/* Handled by alut
		ALCcontext *pContext;
		ALCdevice *pDevice;

		pContext = alcGetCurrentContext();
		pDevice = alcGetContextsDevice(pContext);

		alcMakeContextCurrent(NULL);
		alcDestroyContext(pContext);
		alcCloseDevice(pDevice);
		 */


	}

	void AudioEngineOAL::deleteSoundBuffer(SoundBuffer* snd)
	{
		alDeleteBuffers(1, &snd->bufferID);
		ResourceManager::getSingleton()->removeResource(snd);
		snd->removeRef();
		delete snd;
	}

	void AudioEngineOAL::init()
	{

	}

	UInt AudioEngineOAL::createSoundBuffer()
	{
		UInt uiBuffer;
		alGenBuffers( 1, &uiBuffer );
		return uiBuffer;
	}

	void AudioEngineOAL::playSound(SoundBuffer* snd, const Vec3& pos)
	{
		// Attach Source to Buffer
		alSourcei( source[0], AL_BUFFER, snd->bufferID );
		alSource3f( source[0], AL_POSITION, pos.x, pos.y, pos.z );
		// Play Source
		alSourcePlay( source[0] );

	}

	void AudioEngineOAL::setListenerPos(const Vec3& pos)
	{
		AudioEngine::setListenerPos(pos);
		alListener3f(AL_POSITION, pos.x, pos.y, pos.z);

	}

	SoundBuffer* AudioEngineOAL::loadFromWAVFile(const SypX::String &name)
	{
		SoundBuffer* buff = static_cast<SoundBuffer*>(SypX::ResourceManager::getSingleton()->checkResource(name));
		if(buff)
		{
			if(buff->getNumRef() == 0)
			{//This means that the buffer was already correctly deleted but not cleared from memory yet
				buff->addRef();		//revive it
			}
			return buff;
		}

		buff = new SoundBuffer();
		buff->addRef();	//again, its to prevent resource management since this is not referenced
		String path = Engine::getFilePath(name);
		buff->bufferID = alutCreateBufferFromFile (path.c_str());

			//alBufferData(buff->bufferID, eBufferFormat, pData, iDataSize, iFrequency);
			if (alGetError() == AL_NO_ERROR)
			{
				buff->setFileName(name);
				return buff;
			}

		return 0;
	}
}
